


.SEGMENT "CODE"
.EXPORT _outputCharML, _outputStringML
.IMPORT _putchar, popa, popax, pusha, pushax
.IMPORT _writeByteRS232, _twistCharMLPtoA

OD_SCREEN = $02
OD_MODEM  = $04

EN_ASCII =  $00
EN_PETSCII= $01
EN_ATASCII= $02
EN_ANSI =   $03

ZP_LO   = $FB
ZP_HI   = $FC

; bool __fastcall__ outputStringML(encoding_t encoding, outDirections_t directions, const char *value);
.proc _outputStringML
    sta OS_STRING       ; Keep the string
    stx OS_STRING + 1   

    lda ZP_LO             ; Store off ZP
    pha 
    lda ZP_HI
    pha

    lda OS_STRING       ; Create indirect reference
    sta ZP_LO
    stx ZP_HI
    
    jsr popax           ; get direction from stack
    sta OC_DIRECTION    ; Store in ZP

    jsr popax           ; get system encoding from stack
    sta OC_ENCODING     ; Store in ZP

    jsr popax           ; get current encoding from stack
    sta OC_CURRENT_ENC  ; Store in ZP

    lda OS_STRING       ; Get String back
    cmp #$00            ; Check for null
    bne :+
    lda OS_STRING + 1   ; GEt string back high
    cmp #$00            ; Check for null
    bne :+
    jmp done            ; Do nothing

:   ldy #$00            ; Initialize indexer

:   lda (ZP_LO),y         ; Get a character    
    cmp #$00            ; Is it null?
    beq done

    tya                 ; Store Y on stack
    pha

    ldx #$00            ; Init X
    lda OC_CURRENT_ENC  ; get current encoding
    jsr pushax          ; put on stack

    lda OC_ENCODING     ; get system encoding
    jsr pushax          ; put on stack

    lda OC_DIRECTION    ; Get direction
    jsr pushax          ; put on stack

    pla                 ; Retrieve Y from stack
    tay
    pha                 ; put it back on stack
    lda (ZP_LO),y         ; get character
    jsr _outputCharML   ; write it to screen and/or modem

    pla                 ; Retrieve Y from stack
    tay
    iny                 ; Increment Y
    tya                 ; Move to A
    cmp #$00            ; Compare to 0, means we have reached 256-byte limit.
    bne :-              ; Not equal, get next character.

done:
    pla                 ; Restore ZP
    sta ZP_HI
    pla
    sta ZP_LO

    ldx #$00            ; Init
    lda #$01            ; true
    rts
.endproc

; void fastcall outputCharML(unsigned, unsigned, unsigned, char)
.proc _outputCharML
    sta OC_CHAR         ; Keep the character
    
    jsr popax           ; get direction from stack
    sta OC_DIRECTION    ; Store in ZP

    jsr popax           ; get system encoding from stack
    sta OC_ENCODING     ; Store in ZP

    jsr popax           ; get current encoding from stack
    sta OC_CURRENT_ENC  ; Store in ZP

    lda OC_CHAR         ; Get Character back
    cmp #$00            ; Check for null
    bne :+
    jmp done            ; Do nothing


:   lda OC_DIRECTION    ; Retrieve direction
    and #OD_SCREEN      ; test for OD_SCREEN
    cmp #OD_SCREEN
    bne :+
    
    lda OC_CHAR         ; Get Character
    jsr _putchar        ; Output to STDOUT

:   lda OC_DIRECTION    ; Get the direction back
    and #OD_MODEM       ; OD_MODEM
    cmp #OD_MODEM
    bne done

    lda OC_CURRENT_ENC  ; Retrieve current encoding
    cmp OC_ENCODING     ; Test for ASCII
    bne :+              ; Are different

    lda OC_CHAR         ; Get the character back into A
    jmp :++             ; Jump to write

    ; Twist the character
:   lda $EA             ; Preserve $EA
    pha

    lda OC_CHAR         ; Retrieve char
    
    sta $EA                 ; Reoutine expects char to twist in EA
    jsr _twistCharMLPtoA    ; Twist
    lda $EA                 ; Result is returned in EA
    sta OC_CHAR             ; Keep the result

    pla                 ; Restore $EA
    sta $EA

    lda OC_CHAR

    cmp #$00
    beq done

    cmp #$0D            ; Test against ENTER
    bne :+              ; Not ENTER, next

    lda #$0A            ; 13 -> 10 for ASCII

:   jsr _writeByteRS232 ; Output the char to RS232

done:
    rts
.endproc

OC_CHAR:         .byte $00
OC_DIRECTION:    .byte $00
OC_ENCODING:     .byte $00
OC_CURRENT_ENC:  .byte $00

OS_STRING:       .word $0000